﻿using System;
using System.IO;
using System.Reflection;
using System.Text;
using ZilLion.Service.Core.ConfigManager.Provider;

namespace ZilLion.Service.Core.Log.Config
{
    /// <summary>
    ///     NlogConfigProvider
    /// </summary>
    public class NlogConfigProvider : JsonConfigProvider
    {
        private readonly object _nlogconfigSavelock = new object();

        public override object LoadConfig()
        {
            var result = base.LoadConfig();

            #region 刷新Nlog相关配置

            var nlogConfig = CurrentConfigInstance as LoggerConfig;


            if (nlogConfig != null)
                if (IsNlogConfigChanged(nlogConfig))
                {
                    var configpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "NLog.config");
                    File.WriteAllText(configpath,
                        CreateNLogConfig(nlogConfig), Encoding.UTF8);
                }

            #endregion

                    return result;
        }

        public override void SaveConfig(object config)
        {
            #region 刷新Nlog相关配置

            base.SaveConfig(config);

            var nlogConfig = CurrentConfigInstance as LoggerConfig;
            if (nlogConfig != null)
                if (IsNlogConfigChanged(nlogConfig))
                {
                    var configpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "NLog.config");
                    lock (_nlogconfigSavelock)
                    {
                        File.WriteAllText(configpath,
                              CreateNLogConfig(nlogConfig), Encoding.UTF8);
                    }
                }

            #endregion
        }

        #region 配置

        /// <summary>
        ///     获取文件
        /// </summary>
        /// <returns></returns>
        private string GetNlogConfigTemplate()
        {
            using (
                var templateStream =
                    Assembly.GetExecutingAssembly().GetManifestResourceStream("ZilLion.Service.Core.Log.NLog.ct"))
            {

                if (templateStream!=null)
                {
                    try
                    {
                        StreamReader reader = new StreamReader(templateStream, Encoding.UTF8);
                        var result= reader.ReadToEnd();
                        reader.Dispose();
                        return result;
                    }
                    finally
                    {
                        templateStream.Close();

                        templateStream.Dispose();
                    }

                }
                return String.Empty;

            }
        }

        private bool IsNlogConfigChanged(LoggerConfig jsonconfig)
        {
            var configpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "NLog.config");
            if (!File.Exists(configpath))
            {
                return true;
            }
            if (jsonconfig.ForceRefreshNlog)
            {
                var newconfighash = CreateNLogConfig(jsonconfig).ToMd5Hash();
                var oldhash = File.ReadAllText(configpath, Encoding.UTF8).ToMd5Hash();
                return newconfighash != oldhash;
            }
            return false;
        }

        private string CreateNLogConfig(LoggerConfig jsonconfig)
        {
            var appname = "ZilLionApp";
            var entryAssembly = Assembly.GetEntryAssembly();
            if (entryAssembly != null)
                appname = Path.GetFileName(Assembly.GetEntryAssembly().GetName().Name);
            var templatecontent = GetNlogConfigTemplate();
            var mongoConnectionString = jsonconfig.NLogMongoConnectionString;
            var mongoDatabaseName = jsonconfig.NLogMongoDatabaseName;
            templatecontent = templatecontent.Replace("@MongoConnectionString",
                mongoConnectionString);
            templatecontent = templatecontent.Replace("@MongoCollectionName",
                (jsonconfig.MongoCollectionName.IsNullOrEmpty() ? appname : jsonconfig.MongoCollectionName)
                + DateTime.Now.ToString("yyyyMMdd"));
            templatecontent = templatecontent.Replace("@MongoDatabaseName", mongoDatabaseName);
            var configcontent
                = templatecontent;

            return configcontent;
        }

        #endregion
    }
}